<template>
  <section>
    <div class="leaflet-map" id="leafletMap"></div>
    <map-menu
      @drawCircle="drawCircle"
      @drawPolygon="drawPolygon"
      @drawPoint="drawPoint"
      @drawPopur="drawPopur"
      @setMapObjPopup="setMapObjPopup"
      @smallMap="smallMap"
      @bigMap="bigMap"
      @flyTo="flyTo"
      @addVideoToMap="addVideoToMap"
      @clearMap="clearMap"
      @drawPolyLine="drawPolyLine"
      @radar="drawRadar"
      @drawRadarArea="drawArea"
      @drawAnimationLine="drawAnimationLine"
      @testSemi="testSemi"
      @drawLineDistance="drawLineDistance"
    ></map-menu>
  </section>
</template>

<script>
import myMap from "./data/map";
import { mapImgUrl, mapFontUrl } from "./data/index";
import MapMenu from "./MapMenu";
import MapTest from 'leaflet-semicircle'

const MAP_TOKEN = "pk.eyJ1Ijoid2FuZ2d1b2ZlbmciLCJhIjoiY2wydHIyNjYxMDY3djNrbXVldWkxcXh5bCJ9.xh9BUnjS1tAo22Cdhqp28A"

export default {
  name: "LeafLetMap",
  components: {
    MapMenu,
  },
  mounted() {
    this.initalMap();
  },
  data() {
    return {
      marker: "",
      circle: "",
      polygon: "",
      zoomLevel: 0,
      videoOverlay: '',
      bounds: '',
      polyline: '',
      RAF: '',
      cirInfo: {
        count: 0,
        list: []
      },
      testMove: ''
    };
  },
  methods: {
    initalMap() {
      // myMap = this.$leaflet.map("leafletMap").setView([51.505, -0.09], 13);

      myMap = this.$leaflet.map("leafletMap").setView([40.51, -122.68], 5);
      

      this.drawLeaflet(mapImgUrl, mapFontUrl);
      // this.getLatlng();
    },
    /**
     * @绘制地图leaflet天地图
     */
    drawLeaflet(imgUrl, fontUrl) {
      this.$leaflet.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=' + MAP_TOKEN, {
          attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
          maxZoom: 18,
          id: 'mapbox/streets-v11',
          tileSize: 512,
          zoomOffset: -1,
          accessToken: MAP_TOKEN
      }).addTo(myMap);
      // this.mapImg = this.$leaflet
      //   .tileLayer(imgUrl + "&tk=d7743e3458d99abf8fdd6d79dbbe5368", {
      //     maxZoom: 23,
      //     tileSize: 256,
      //     zoomOffset: 1,
      //     minZoom: 1,
      //   })
      //   .addTo(myMap);
      // this.mapFont = this.$leaflet
      //   .tileLayer(fontUrl + "&tk=d7743e3458d99abf8fdd6d79dbbe5368", {
      //     maxZoom: 23,
      //     tileSize: 256,
      //     zoomOffset: 1,
      //     minZoom: 1,
      //   })
      //   .addTo(myMap);
    },
    drawPoint() {
      this.marker = this.$leaflet.marker([51.5, -0.09]).addTo(myMap);
    },
    drawCircle() {
      this.circle = this.$leaflet
        .circle([51.508, -0.11], {
          color: "red",
          fillColor: "#f03",
          fillOpacity: 0.5,
          radius: 500,
        })
        .addTo(myMap);
    },
    drawPolygon() {
      this.polygon = this.$leaflet
        .polygon([
          [51.509, -0.08],
          [51.503, -0.06],
          [51.51, -0.047],
        ])
        .addTo(myMap);
    },
    setMapObjPopup() {
      this.marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
    },
    drawPopur() {
      this.$leaflet
        .popup()
        .setLatLng([51.5, -0.09])
        .setContent("<h1 style='color:red'>asdasd</h1>I am a standalone popup.")
        .openOn(myMap);
    },
    /**
     * @ 标记经纬度
     */
    getLatlng() {
        const popup = this.$leaflet.popup()
      myMap.on("click", (e) => {
        // console.log(e.latlng);
        popup
          .setLatLng(e.latlng)
          .setContent("<h1>You click at map " + e.latlng.toString() + "</h1>")
          .openOn(myMap);
      });
    },
    smallMap() {
      this.zoomLevel -= 1
      myMap.setZoom(this.zoomLevel)
    },
    bigMap() {
      this.zoomLevel += 1
      myMap.setZoom(this.zoomLevel)
    },
    flyTo(optInfo) {
      myMap.flyTo(optInfo)
    },
    addVideoToMap(){
      this.bounds = this.$leaflet.latLngBounds([[ 32, -130], [ 13, -100]]);
      this.$leaflet.rectangle(this.bounds).addTo(myMap);

      // 添加图片
      // var overlay = L.imageOverlay( imageUrl, bounds, options );

      var videoUrls = [
        'https://www.mapbox.com/bites/00188/patricia_nasa.webm',
        'https://www.mapbox.com/bites/00188/patricia_nasa.mp4'
      ];

      var bounds = this.$leaflet.latLngBounds([[58, -70], [ 40, -40]]);

      myMap.fitBounds(bounds)

      this.videoOverlay = this.$leaflet.videoOverlay( videoUrls, bounds, {
          opacity: 0.8
      }).addTo(myMap);
    },
    clearMap() {
      this.videoOverlay.remove()
    },
    drawPolyLine() {
      let latlngs = [
          [45.51, -122.68],
          [37.77, -122.43],
          // 测试动态划线
          // [34.04, -118.2],
          // [34.66, -112.85],
          // [40, -112,32],
          // [44.33, -117.46]
      ];
      this.polyline = this.$leaflet.polyline(latlngs, {color: 'red', weight: 10}).addTo(myMap)

      myMap.fitBounds(this.polyline.getBounds())

      this.polyline.on('click', (e) => {
        console.log("click")
        let popup = this.$leaflet.popup()
        popup.setLatLng(e.latlng).setContent(`<h1>Click ${e.latlng}</h1>`).openOn(myMap)
      })

      // this.polyline.on('dblclick', (e) => {
      //   console.log("dblclick")
      //   let popup = this.$leaflet.popup()
      //   popup.setLatLng(e.latlng).setContent(`<h1>dblclick ${e.latlng}</h1>`).openOn(myMap)
      // })

      // this.polyline.on('mousedown', (e) => {
      //   console.log("mousedown")

      //   let popup = this.$leaflet.popup()
      //   popup.setLatLng(e.latlng).setContent(`<h1>mousedown ${e.latlng}</h1>`).openOn(myMap)
      // })

      // this.polyline.on('mouseup', (e) => {
      //   console.log("mouseup")

      //   let popup = this.$leaflet.popup()
      //   popup.setLatLng(e.latlng).setContent(`<h1>mouseup ${e.latlng}</h1>`).openOn(myMap)
      // })

      this.drawPolyLine_AddLine(latlngs)
    },
    drawPolyLine_AddLine(oldLine) {
      const data = [
        [34.04, -118.2],
        [34.66, -112.85],
        [40, -112,32],
        [44.33, -117.46]
      ]

      data.forEach((item, index) => {
        setTimeout(() => {
          this.polyline.remove()
          oldLine.push(item)
          this.polyline = this.$leaflet.polyline(oldLine, {color: 'red', weight: 10}).addTo(myMap)

          this.polyline.on("click", (e) => {
            let popup = this.$leaflet.popup()
            popup
              .setLatLng(e.latlng)
              .setContent("<h1>You click at line " + e.latlng.toString() + "</h1>")
              .openOn(myMap);
          });
        }, 400 * index)
      })
    },
    drawRadar() {
      const MAX_REDIUS = 600
      const latlng = [51.5, -0.11]
      let circle = this.$leaflet.circle(latlng, {radius: MAX_REDIUS}).addTo(myMap)
      myMap.fitBounds(circle.getBounds())
      let count = 1
      let aniCircle, aniCircle_2, aniCircle_3, aniCircle_4
      let t = setInterval(() => {
        aniCircle && aniCircle.remove()
        aniCircle_2 && aniCircle_2.remove()
        aniCircle_3 && aniCircle_3.remove()
        aniCircle_4 && aniCircle_4.remove()

        aniCircle = this.$leaflet.circle(latlng, {opacity: count / MAX_REDIUS, fillOpacity: 0, radius: count}).addTo(myMap)
        aniCircle_2 = this.$leaflet.circle(latlng, {opacity: (count + 150) / MAX_REDIUS, fillOpacity: 0, radius: count + 150}).addTo(myMap)
        aniCircle_3 = this.$leaflet.circle(latlng, {opacity: (count + 300) / MAX_REDIUS, fillOpacity: 0, radius: count + 300}).addTo(myMap)
        aniCircle_4 = this.$leaflet.circle(latlng, {opacity: (count + 450) / MAX_REDIUS, fillOpacity: 0, radius: count + 450}).addTo(myMap)
        count === 150 ? count=1 : count ++
      })
    },
    drawArea() {
      this.getRadar([50, 30], 2000)
      this.drawRadarPoint()
    },
    getRadar(latlng, maxRadius) {
      let circle = this.$leaflet.circle(latlng, {radius: 1}).addTo(myMap)
      myMap.fitBounds(circle.getBounds(), {maxZoom: 13})
      let count = 0
      let t = setInterval(() => {
        circle && circle.remove()

        circle = this.$leaflet.circle(latlng, {radius: count}).addTo(myMap)

        count === maxRadius ? clearInterval(t) : count += 2
      })
      
      // return circle
    },
    drawRadarPoint() {
      console.log(1)
      let arr = [
          [49.999464, 29.989758],
          [49.988318, 30.00452],
          [50.006746, 30.006924]
        ]

      arr.forEach((item, index) => {
        let popup = this.$leaflet.popup()
        
        let marker = this.$leaflet.marker(item).addTo(myMap);
        marker.on('click', (e) => {
          popup.setLatLng(item).setContent('Point' + index).openOn(myMap)
        })
        marker.bindTooltip("my tooltip text")
      })
    },
    drawAnimationLine() {
      this._drawAnimationLine()
    },
    async _drawAnimationLine() {
      const PIE = 500
      let latlngs = [[45.51, -122.68], [37.77, -122.43], [34.04, -118.2]]
      
      let lastPoint = latlngs.shift()
      let t

      while(latlngs.length > 0) {
          let startPoint = lastPoint
          lastPoint = latlngs.shift()

          let c = {
            lat: (startPoint[0] - lastPoint[0]) / PIE,
            lng: (startPoint[1] - lastPoint[1]) / PIE
          }

          let list = []
          let polyline
          let count = 0
          t = setInterval(() => {
            polyline && polyline.remove()
            list.push([startPoint[0] - (count * c.lat), startPoint[1] - (count * c.lng)])
            polyline = this.$leaflet.polyline(list, {color: 'red'}).addTo(myMap);
            if(count === PIE) {
              clearInterval(t)
              t = null
            } else {
              count++
            }   
          })
      }

      // polyline = this.$leaflet.polyline(latlngs, {color: 'red'}).addTo(myMap);

    },
    testSemi() {
      let count = 0
      let circle = this.$leaflet.circle([51.5, -0.09], {color: '#f03',radius: 500}).addTo(myMap)
      let cirArr = []
      // setInterval( () => {
      //   for(let i = 0; i < 50; i++) {
      //     cirArr[i] && cirArr[i].remove()
      //     cirArr[i] = this.$leaflet.semiCircle([51.5, -0.09], {
      //       radius: 500,
      //       startAngle: (45 + i  * 2) + count,
      //       stopAngle: (47 + i * 2) + count,
      //       fill: true,
      //       fillColor:'#f03',
      //       fillOpacity: (0.02 * i),
      //       color: '#f03',
      //       opacity: 0,
      //     }).addTo(myMap);
      //   }
      //   count++
      // })
      this.testRAF()
      myMap.fitBounds(circle.getBounds())
    },
    testRAF() {
        for(let i = 0; i < 50; i++) {
          this.cirInfo.list[i] && this.cirInfo.list[i].remove()
          this.cirInfo.list[i] = this.$leaflet.semiCircle([51.5, -0.09], {
            radius: 500,
            startAngle: (45 + i  * 2) + this.cirInfo.count,
            stopAngle: (47 + i * 2) + this.cirInfo.count,
            fill: true,
            fillColor:'#f03',
            fillOpacity: (0.02 * i),
            color: '#f03',
            opacity: 0,
          }).addTo(myMap);
        }
        this.cirInfo.count ++
        this.RAF = requestAnimationFrame(this.testRAF)
    },
    drawLineDistance() {
      // 0.000001° ≈ 0.111 m
      let startPoint, lastPoint, points = [];
      let line, r_line
      let centerPoint
      let lastClickTime
      myMap.on('click', (e) => {
        startPoint = e.latlng
        points.push(startPoint)
        if(lastClickTime) {
          if( Date.now() - lastClickTime < 200 ) {
            console.log(myMap)
            // myMap.off('mousemove', this.testMove)
          }
          lastClickTime = Date.now()
        } else {
          lastClickTime = Date.now()
        }
        if(points.length > 1) {
          r_line && r_line.remove()
          r_line = this.$leaflet.polyline(points, {color: 'red'}).addTo(myMap)
        }
        this.testMove = (e) => {
          line && line.remove()
          centerPoint && centerPoint.remove()
          lastPoint = e.latlng
          const c_lat = startPoint['lat'] - lastPoint['lat']
          const c_lng = startPoint['lng'] - lastPoint['lng']
          let c_point = {
            lat: startPoint.lat - c_lat / 2, 
            lng: startPoint.lng - c_lng / 2
          }

          line = this.$leaflet.polyline([startPoint, lastPoint]).addTo(myMap)
          const length = this.point_jl(startPoint, lastPoint)
          let centerText = this.$leaflet.divIcon({
            html: `<span>${length.toFixed(2)}m</span>`,
            iconSize: 0
          })
          centerPoint = this.$leaflet.marker(c_point, {icon: centerText}).addTo(myMap)
        }
        myMap.on('mousemove', this.testMove)
      })
      myMap.on('dblclick', (e) => {
        console.log(2)
        myMap.off()
      })
    },
    point_jl(point_1, point_2) {
      let res = 0
      const EARTH_R = 6371.0 * 1000
      const { lat: X1, lng: Y1 } = point_1
      const { lat: X2, lng: Y2 } = point_2

      const num_1 = Math.sin(Y1) * Math.sin(Y2)
      const num_2 = Math.cos(Y1) * Math.cos(Y2) * Math.cos(X1-X2)
      res = EARTH_R * Math.acos(num_2 + num_1)
      return Math.abs(res)
    }
  },
};
</script>

<style scoped>
.leaflet-map {
  width: 100%;
  height: 400px;
  border: 1px solid red;
}
</style>